<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多边形填充-小试牛刀</title>
    <style>
        canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas width="512" height="512"></canvas>

    <script type="module">
        import { Vector2D } from "/review/common/Vector2D.js";
        // 导入进行三角剖分的库
        import { earcut } from '/common/lib/earcut.js';

        // 参数方程生成坐标点集合
        function parametric(xFunc, yFunc, transFunc){
            return function(start, end, segments = 60, ...args){
                const points = [];
                const s = end - start;
                const e = s / segments;
                for (let i = 0; i <= segments; i++) {
                    const t = start + e * i;
                    const x = xFunc(t, ...args);
                    const y = yFunc(t, ...args);
                    points.push([x, y]);
                }
                return {
                    points
                }
            }
        }

        /**
         * webgl原生五步用法
         * 1.创建webgl上下文
         * 2.创建webgl程序
         * 3.将数据存入缓冲区
         * 4.将数据读取到gpu
         * 5.gpu执行webgl程序
        */
        // 1.
        const canvas = document.querySelector("canvas");
        const gl = canvas.getContext("webgl");

        // 2.
        const vertex = `
            attribute vec2 position;
            void main(){
                gl_PointSize = 1.0;
                gl_Position = vec4(position, 0.0, 1.0);
            }
        `
        const fragment = `
            precision mediump float;

            uniform vec2 color;
            void main(){
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }
        `
        const vertexShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertexShader,vertex);
        gl.compileShader(vertexShader);

        const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragmentShader,fragment);
        gl.compileShader(fragmentShader);

        const program = gl.createProgram();
        gl.attachShader(program,vertexShader);
        gl.attachShader(program,fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        // 3.
        // 不规则多边形的顶点数组
        let vertices = [
            [-0.7, 0.5],
            [-0.4, 0.3],
            [-0.25, 0.71],
            [-0.1, 0.56],
            [-0.1, 0.13],
            [0.4, 0.21],
            [0, -0.6],
            [-0.3, -0.3],
            [-0.6, -0.3],
            [-0.45, 0.0],
        ];

        // // 1.星形线   参数方程x=a*(cost)3   y=a*(sint)3
        // let p = parametric(
        //     (t) => 0.5 * (Math.cos(t) * Math.cos(t) ** 2),
        //     (t) => 0.5 * (Math.sin(t) * Math.sin(t) ** 2)
        // );
        // vertices = p(-3.14, 3.14).points;

        // // 2.椭圆   椭圆的参数方程x=acosθ,y=bsinθ
        // let p = parametric(
        //     (t) => 0.5 * Math.cos(t),
        //     (t) => 0.4 * Math.sin(t)
        // );
        // vertices = p(-3.14, 3.14).points;

        // 3.五角星   椭圆的参数方程   x = 2cos t + 5cos(2t/3)   y = 2sin t - 5sin(2t/3)
        const ps = [new Vector2D(0,100)];
        for (let i = 0; i <= 4; i++) {
            const p = ps[0].copy().rotate(i * Math.PI * 0.4);
            ps.push(p);
        }
        
        vertices = [
            ps[5],
            ps[2],
            ps[4],
            ps[1],
            ps[3]
        ];
        vertices.forEach(item=>{
            item[0] /= 256
            item[1] /= 256
        });
        console.log(vertices)

        const earcutVertices = earcut(vertices.flat(), null, 2);
        console.log(earcutVertices)
        const points = new Float32Array(vertices.flat());
        const cells = new Uint16Array(earcutVertices);
        
        const pointBufferId = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, pointBufferId);
        gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);

        // 4.从刚刚当前设置的缓冲区对象获取数据，设置顶点着色器
        const vPosition = gl.getAttribLocation(program, "position");
        gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(vPosition);

        // 设置三角剖分的缓存数据
        const cellBufferId = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,cellBufferId);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,cells, gl.STATIC_DRAW);

        // 5.
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.drawElements(gl.TRIANGLES, cells.length, gl.UNSIGNED_SHORT,0);

    </script>
</body>
</html>